/*-------------------------------------------------------------------------
File Name: Scpi.c
Function Description: process the string cmd for serial,.
Author: ray.gong (2012-11-10)
Modify history:
-------------------------------------------------------------------------*/

#include <types.h>
#include <osal/osal_task.h>
#include <api/libc/printf.h>
#include <api/libc/string.h>
#include <bus/sci/sci.h>
#include <bus/dog/dog.h>
#include <hld/hld_dev.h>
#include "scpi.h"

static OSAL_ID INPUT_TASK_ID;

#define 	INPUT_TASK_PRIORITY		OSAL_PRI_NORMAL
#define 	INPUT_TASK_STACKSIZE		0x1000
#define 	INPUT_TASK_QUANTUM		10

#define DBG_INTERVAL     500
extern stDbgCmd g_stDbgCmdStr;
extern stDbgCmdNode g_stDbgCmdNode[];

BYTE *g_pbyRcvStringBuf=NULL;
BYTE *g_pbySndStringBuf=NULL;
/*-------------------------------------------------------------------------
Function Name: GetUserCmdString
Function Description: parase the string to cmd and param.
Author: ray.gong (2012-11-10)
Input parameter: szInput:input string from terminal;
				 
Output parameter:
				szCmd:user command
				argc:point to user comannd param cnt
				argv:all user command param after parase;
Return Value:SUCCESS:RET_SUCCESS: return success;RET_FAILURE: retrun failed
Modify history:
-------------------------------------------------------------------------*/
UINT32 GetUserCmdString(CHAR *szInput,CHAR *szCmd,UINT32 *argc,CHAR *argv[])
{
    UINT32 timeout = 1000;
	BYTE byRcvCharTmp=0;
	UINT32 i=0;
	UINT32 uiCmdIDEndPos=0;
	UINT32 uiParamCnt=0;
	UINT32 uiParamPosStr=0;
	UINT32 uiParamPosEnd=0;

	if((NULL==szCmd)||(NULL==argc)||(NULL==argv))
	{
		return -1;
	}
	
	if(strlen(szInput)>0)
	{
		for(i=0;i<strlen(szInput);i++)
		{
			if(i<UART_CMD_STR_LEN_MAX)
			{
				byRcvCharTmp=szInput[i];

				switch(byRcvCharTmp)
				{
					case ' ':
						uiCmdIDEndPos=i;
						uiParamPosStr=i+1;
						strncpy(szCmd,szInput,uiCmdIDEndPos);
						szInput[i]=byRcvCharTmp;
						break;
					case ',':
						uiParamPosEnd=i;
						strncpy(argv[uiParamCnt],szInput+uiParamPosStr,((uiParamPosEnd-uiParamPosStr)<0)?0:(uiParamPosEnd-uiParamPosStr));
						uiParamPosStr=uiParamPosEnd+1;
						uiParamCnt++;
						szInput[i]=byRcvCharTmp;
						break;
					case '\r':
					case '\n':
						//if(0!=uiParamPosEnd)
						{
							uiParamPosEnd=i;
							strncpy(argv[uiParamCnt],szInput+uiParamPosStr,((uiParamPosEnd-uiParamPosStr)<0)?0:(uiParamPosEnd-uiParamPosStr));
							uiParamPosStr=uiParamPosEnd+1;
							uiParamCnt++;
							szInput[i]=byRcvCharTmp;
						}
						szInput[i]='\0';
						break;						
					default:
						szInput[i]=byRcvCharTmp;
						break;				
				}

			}
	    }
		
		if(0==uiCmdIDEndPos)
		{
			strncpy(szCmd,szInput,UART_CMD_ID_LEN_MAX);
		}
		
		*argc=uiParamCnt;

		//MEMSET(szInput,0,UART_CMD_STR_LEN_MAX+1);
		if(strlen(szCmd)>0)
		{
			return 0;
		}
		else
		{
			return -1;
		}
		
	}
	return -1;
}

OSAL_ID g_MsgQIdScpi;
static void ScpiTask()
{
    UINT32 uiRtn=-1;
	UINT32 i=0;
	UINT32 j=0;
	BOOL bFindCmd=FALSE;
	UINT32 iCnt=USER_CMD_COUNT_MAX;
	UINT32 uiMsgSize=0;

	MEMSET(&g_stDbgCmdStr,0,sizeof(stDbgCmd));
	//*(g_stDbgCmdStr.argv)=NULL;
	
	(UINT32 *)(g_stDbgCmdStr.argv) = (UINT32 *)MALLOC(USER_CMD_PARAM_COUNT_MAX);

	MEMSET((g_stDbgCmdStr.argv),0,sizeof(UINT32)*USER_CMD_PARAM_COUNT_MAX);

	for(i=0;i<USER_CMD_PARAM_COUNT_MAX;i++)
	{
		(CHAR*)(*((CHAR **)((CHAR **)g_stDbgCmdStr.argv+i)))=MALLOC(USER_CMD_PARAM_STR_LEN_MAX);
		MEMSET((*((CHAR **)((CHAR **)g_stDbgCmdStr.argv+i))),0,USER_CMD_PARAM_STR_LEN_MAX);
	}
	
	while(1)
	{
		osal_task_sleep(DBG_INTERVAL);
		
		bFindCmd=FALSE;
		if((NULL==g_pbyRcvStringBuf)||(NULL==g_pbySndStringBuf))
		{
			return;
		}
		MEMSET(g_pbyRcvStringBuf,0,UART_CMD_STR_LEN_MAX+1);
		uiRtn = osal_msgqueue_receive(g_pbyRcvStringBuf,&uiRtn,g_MsgQIdScpi,100);
		if(OSAL_E_OK != uiRtn)
		{
			continue;
		}

		
		
	    uiRtn = GetUserCmdString(g_pbyRcvStringBuf,g_stDbgCmdStr.acCmdID,&(g_stDbgCmdStr.uiCmdParamCnt),g_stDbgCmdStr.argv);
		if(0==uiRtn)
		{
			//libc_printf("\n[get szCmd]=\"%s\"",g_stDbgCmdStr.acCmdID);

			for(i=0;((i<iCnt)&&(0!=strcmp(g_stDbgCmdStr.acCmdID,"NULL"))&&(0!=strcmp(g_stDbgCmdStr.acCmdID,"")));i++)
			{
				if(0==strcmp(g_stDbgCmdStr.acCmdID,g_stDbgCmdNode[i].acCmdID))
				{
					uiRtn=g_stDbgCmdNode[i].CmdHandle(&(g_stDbgCmdStr.uiCmdParamCnt),g_stDbgCmdStr.argv,g_stDbgCmdStr.acCmdOutPut);

					libc_printf("\r\nALi>%s",g_pbyRcvStringBuf);

					
					if(0==uiRtn)
					{
						libc_printf("\r\n0.%s",g_stDbgCmdStr.acCmdOutPut);
					}
					else
					{
						libc_printf("\r\n-1.%s",g_stDbgCmdStr.acCmdOutPut);
					}
					bFindCmd=TRUE;
					break;
				}

			}

			if(!bFindCmd)	
			{
				libc_printf("\r\nALi>%s",g_pbyRcvStringBuf);
				libc_printf("\r\nUndefine Command!");
			}
			MEMSET(g_pbyRcvStringBuf,0,UART_CMD_STR_LEN_MAX+1);
			for(i=0;i<g_stDbgCmdStr.uiCmdParamCnt;i++)
			{
				//libc_printf("\nargV[%d]=\"%s\"",i,g_stDbgCmdStr.argv[i]);
				MEMSET((*((CHAR **)((CHAR **)g_stDbgCmdStr.argv+i))),0,USER_CMD_PARAM_STR_LEN_MAX);
			}
			g_stDbgCmdStr.uiCmdParamCnt=0;
			MEMSET(g_stDbgCmdStr.acCmdID,0,UART_CMD_ID_LEN_MAX+1);
			MEMSET(g_stDbgCmdStr.acCmdOutPut,0,UART_CMD_OUTPUT_LEN_MAX+1);
					
			libc_printf("\r\n");
		}

	}
}

//-----------------------------------------------------------------------------
// FUNCTION:    UIKeyInit:
//
// DESCRIPTION: init the keyboard devices(including frontpanel and remote controller) hardware
//
// RETURN:      True	Successful
//              False	Error when init the hardware
//
// NOTES:       
//
//-----------------------------------------------------------------------------
UINT8 scpi_Init()
{	
	OSAL_T_CTSK		t_ctsk;
	INT32	retVal;
	UINT32	i;
	ID  			control_task_id ;//= OSAL_INVALID_ID;
	OSAL_T_CMBF		t_cmbf;

    //t_cmbf.mbfatr = TA_TFIFO;
	t_cmbf.bufsz	= SCPI_MBF_SIZE * sizeof(CHAR);
	t_cmbf.maxmsz	= SCPI_MBF_SIZE * sizeof(CHAR);
	t_cmbf.name[0]		= 'c';
	t_cmbf.name[1]		= 'm';
	t_cmbf.name[2]		= 'd';

	g_pbySndStringBuf=MALLOC(UART_CMD_STR_LEN_MAX+1);
	if(NULL == g_pbySndStringBuf)
	{
		libc_printf("\nmalloc g_pbySndStringBuf failed\n");
		return FALSE;
	}
	MEMSET(g_pbySndStringBuf,0,UART_CMD_STR_LEN_MAX+1);
	
	g_pbyRcvStringBuf=MALLOC(UART_CMD_STR_LEN_MAX+1);
	if(NULL == g_pbyRcvStringBuf)
	{
		libc_printf("\nmalloc g_pbyRcvStringBuf failed\n");
		return FALSE;
	}
	MEMSET(g_pbyRcvStringBuf,0,UART_CMD_STR_LEN_MAX+1);
	
	g_MsgQIdScpi = OSAL_INVALID_ID;
	control_task_id = OSAL_INVALID_ID;
	g_MsgQIdScpi = osal_msgqueue_create(&t_cmbf);
	if(OSAL_INVALID_ID == g_MsgQIdScpi)
	{
		libc_printf("\ncre_mbf g_MsgQIdScpi failed\n");
		return FALSE;
	}
	

	t_ctsk.stksz	= 	INPUT_TASK_STACKSIZE * 2;
	t_ctsk.quantum	= 	INPUT_TASK_QUANTUM;
	t_ctsk.itskpri	= 	INPUT_TASK_PRIORITY;
	t_ctsk.name[0]	= 'C';
	t_ctsk.name[1]	= 'M';
	t_ctsk.name[2]	= 'D';
	t_ctsk.task = (FP)ScpiTask;
	control_task_id = osal_task_create(&t_ctsk);
	if(control_task_id==OSAL_INVALID_ID)
		return FALSE;

	return TRUE;
}


